import os
import threading
import time
import tkinter
from tkinter import filedialog

import comtypes.client
import fitz

running = True


def convert_word_to_pdf(file_tup):
    doc_file, pdf_file = file_tup
    word = comtypes.client.CreateObject('Word.Application')
    doc = word.Documents.Open(doc_file)
    doc.SaveAs(pdf_file, FileFormat=17)
    doc.close()
    word.Quit()


def conver_img(tup_file):
    pdf, img, x, y = tup_file
    doc = fitz.open(pdf)
    for pg in range(doc.pageCount):
        page = doc[pg]
        zoom_x = x
        zoom_y = y
        trans = fitz.Matrix(zoom_x, zoom_y).preRotate(0)
        pm = page.getPixmap(matrix=trans, alpha=False)
        pm.writePNG(img)


class Frame:
    def __init__(self):
        root = tkinter.Tk()
        root.title('Word转PDF-图')
        root.resizable(width=False, height=False)    # 禁止窗口宽度和高度拉伸
        self.logText = tkinter.Text(root, width=58)  # 日志信息输出框
        self.logText.grid(row=0, column=2, rowspan=20, padx=10, pady=10)
        self.logText.bind('<KeyPress>', lambda e: 'break')  # 绑定键盘输入 取消所有的输入

        self.win_print('转换进程：')
        self.win_print('=' * 58)

        self.path = tkinter.StringVar()
        self.entry = tkinter.Entry(root, textvariable=self.path)
        self.entry.grid(row=0, column=1, padx=10, pady=0)
        tkinter.Button(root, text='选择文件夹', command=self.select_file).grid(row=1, column=1, columnspan=1)

        start_btn = tkinter.Button(text='开始', command=lambda: thread_it(self.turn,))
        start_btn.grid(row=2, column=1, columnspan=1)

        clear_input = tkinter.Button(root, text='清空输入框', command=self.clearinput)
        clear_input.grid(row=3, column=1, columnspan=1)
        root.mainloop()

    def win_print(self, text):                          # 输出到主窗口的日志框
        self.logText.insert(tkinter.END, text + '\n')   # 光标移到文本末 插入内容并换行
        self.logText.see(tkinter.END)

    def clearinput(self):
        self.entry.delete(0, 'end')  # 清空输入框

    def turn(self):
        self.logText.delete(3.0, 'end')
        self.win_print('')
        global running
        if not running:     # 避免再次按到开始打断运行
            return
        doc_folder = self.entry.get()
        parent_folder = '\\'.join(doc_folder.split('/')[:-1])
        pdf_folder = parent_folder + '\\' + 'pdf文件夹'
        img_folder = parent_folder + '\\' + '图片文件夹'
        if not os.path.exists(pdf_folder):
            os.makedirs(pdf_folder)
        if not os.path.exists(img_folder):
            os.makedirs(img_folder)
        # 拼接文件完整路径
        doc_ls = list(map(lambda x: doc_folder + '\\' + x, os.listdir(doc_folder)))
        pdf_ls = list(map(lambda x: pdf_folder + '\\' + x.split('.')[0] + '.pdf', os.listdir(doc_folder)))
        img_ls = list(map(lambda x: img_folder + '\\' + x.split('.')[0] + '.png', os.listdir(doc_folder)))
        li = [(i, j, k) for i, j, k in zip(doc_ls, pdf_ls, img_ls)]
        running = False
        for n, i in enumerate(li):    # 转换过程无法并发，只能慢慢循环了
            if not os.path.exists(i[1]):
                convert_word_to_pdf(i[:2])
                self.win_print('[%d-%d]已生成PDF\t\t\t%s\t\t\t%s' % (len(li), n+1, i[1].split('\\')[-1], time.strftime('%H:%M:%S', time.localtime(time.time()))))
                conver_img((i[1], i[2], 2, 2))
                self.win_print('[%d-%d]已生成图片\t\t\t%s\t\t\t%s' % (len(li), n+1, i[2].split('\\')[-1], time.strftime('%H:%M:%S', time.localtime(time.time()))))
            else:
                self.win_print('[%d-%d]已有重名PDF\t\t\t%s\t\t\t%s' % (len(li), n+1, i[1].split('\\')[-1], time.strftime('%H:%M:%S', time.localtime(time.time()))))
        self.win_print('转换完毕！')
        running = True      # 运行完了可以恢复为True，恢复开始功能

    def select_file(self):
        path_ = filedialog.askdirectory()
        self.path.set(path_)


def thread_it(func, *args):
    # 将函数打包进线程，免界面卡死
    t = threading.Thread(target=func, args=args)
    t.setDaemon(True)
    t.start()
    # 阻塞将会再次卡死界面
    # t.join()


if __name__ == '__main__':
    # main()
    Frame()
